#include <iostream>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <chrono>
#include <functional>
#include <atomic>
#include <memory>

class PeriodicTaskManager {
public:
	using Task = std::function<void()>;

	// 添加周期性任务
	void addTask(Task task, std::chrono::milliseconds interval) {
		std::lock_guard<std::mutex> lock(m_mutex);
		m_tasks.emplace_back(std::make_shared<TaskInfo>(task, interval));
		m_cond.notify_one(); // 通知调度线程有新任务
	}

	// 启动调度器
	void start() {
		m_running = true;
		m_thread  = std::thread(&PeriodicTaskManager::run, this);
	}

	// 停止调度器（等待当前执行中的任务完成）
	void stop() {
		{
			std::lock_guard<std::mutex> lock(m_mutex);
			m_running = false;
			m_cond.notify_all(); // 唤醒调度线程，使其能检查 m_running
		}
		if (m_thread.joinable()) {
			m_thread.join();
		}
	}

	~PeriodicTaskManager() { stop(); }

private:
	struct TaskInfo {
		Task                                  task;
		std::chrono::milliseconds             interval;
		std::chrono::steady_clock::time_point nextRunTime;

		TaskInfo(Task t, std::chrono::milliseconds i) : task(t), interval(i), nextRunTime(std::chrono::steady_clock::now() + i) {}
	};

	std::vector<std::shared_ptr<TaskInfo>> m_tasks;
	std::mutex                             m_mutex;
	std::condition_variable                m_cond;
	std::thread                            m_thread;
	std::atomic<bool>                      m_running{false};

	// 调度线程的主循环
	void run() {
		while (m_running) {
			std::unique_lock<std::mutex> lock(m_mutex);

			if (m_tasks.empty()) {
				// 没有任务，等待新任务通知
				m_cond.wait(lock, [this] { return !m_running || !m_tasks.empty(); });
				continue;
			}

			// 找出最近要执行的任务
			auto now          = std::chrono::steady_clock::now();
			auto nextTaskTime = now + std::chrono::hours(1); // 初始化为一个较大的时间

			for (auto &taskInfo: m_tasks) {
				if (taskInfo->nextRunTime <= now) {
					// 需要执行的任务
					lock.unlock(); // 执行任务前解锁，避免长时间阻塞
					try {
						taskInfo->task(); // 执行任务
					} catch (const std::exception &e) {
						std::cerr << "Task exception: " << e.what() << std::endl;
					}
					lock.lock(); // 重新加锁，继续处理

					// 更新下次执行时间
					taskInfo->nextRunTime = now + taskInfo->interval;
				}

				// 更新最近要执行的任务时间
				if (taskInfo->nextRunTime < nextTaskTime) {
					nextTaskTime = taskInfo->nextRunTime;
				}
			}

			// 计算需要等待的时间
			if (nextTaskTime > now) {
				m_cond.wait_until(lock, nextTaskTime);
			}
		}
	}
};

// 示例任务
void syncData() { std::cout << "[" << std::chrono::system_clock::now().time_since_epoch().count() << "] Syncing data..." << std::endl; }

void cleanupExpiredServices() { std::cout << "[" << std::chrono::system_clock::now().time_since_epoch().count() << "] Cleaning expired services..." << std::endl; }

void cleanupMultiSessions() { std::cout << "[" << std::chrono::system_clock::now().time_since_epoch().count() << "] Cleaning multi sessions..." << std::endl; }

int main() {
	PeriodicTaskManager manager;
	manager.start();

	// 添加不同周期的任务
	manager.addTask(syncData, std::chrono::seconds(3));               // 每3秒执行一次
	manager.addTask(cleanupExpiredServices, std::chrono::seconds(5)); // 每5秒执行一次
	manager.addTask(cleanupMultiSessions, std::chrono::seconds(7));   // 每7秒执行一次

	// 运行一段时间后停止
	std::this_thread::sleep_for(std::chrono::seconds(20));
	manager.stop();

	return 0;
}
